home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / networking / ip / ka9q / MacBMsrc.hqx / Mac bm Project / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-23  |  19.1 KB  |  907 lines

  1. /*
  2.  *    Simple mail user interface for KA9Q IP/TCP package.
  3.  *    A.D. Barksdale Garbee II, aka Bdale, N3EUA
  4.  *    Copyright 1986 Bdale Garbee, All Rights Reserved.
  5.  *    Permission granted for non-commercial copying and use, provided
  6.  *    this notice is retained.
  7.  *    Copyright 1987 1988 Dave Trulli NN2Z, All Rights Reserved.
  8.  *    Permission granted for non-commercial copying and use, provided
  9.  *    this notice is retained.
  10.  *
  11.  * revision history:
  12.  *
  13.  *  v3.3 880417 D. Trulli nn2z
  14.  *  v3.2 880314 D. Trulli nn2z
  15.  *  v3.1 880117 D. Trulli nn2z
  16.  *    Add multiple arguments mail commands.
  17.  *    Send to multiple users.
  18.  *    Add status commands;
  19.  *  v3.0 871225 D. Trulli nn2z
  20.  *    Heavily restructured program to use a index array of message.
  21.  *    More compatible with UNIX type mail commands.
  22.  *  v2.7 871214 D. Trulli nn2z
  23.  *    Cleaned up header and message parsing to prevent lock up.
  24.  *    Revised command structure.
  25.  *  v2.6 870826 Bdale
  26.  *    integrate PA0GRI's interface/gateway to the WA7MBL PBBS
  27.  *  v2.5 870713 Bdale
  28.  *      integrate additional patches from PA0GRI, minor cleanup
  29.  *  v2.4 870614 - P. Karn
  30.  *      "smart gateway" function moved to smtp client code in net.exe.
  31.  *    User interface for sending mail reworked to resemble Berkeley Mail
  32.  *  v2.3 870524
  33.  *      Extensive addition/revision by Gerard PA0GRI.  Now supports a healthy
  34.  *      set of real commands.  
  35.  *  v2.1,2.2
  36.  *      exact change history lost.
  37.  *  v2.0 c.870115
  38.  *      First version with command parser, only send and quit work.
  39.  *  v1.0
  40.  *      First attempt.  Send messages only.
  41.  */
  42.  
  43. #include <stdio.h>
  44. #include <ctype.h>
  45. #include "global.h"
  46. #if    MAC
  47. #include <strings.h>
  48. #include <time.h>
  49. #else
  50. #include <string.h>
  51. #endif
  52. #include "bm.h"
  53.  
  54. #ifdef MAC
  55. extern char applroot[];
  56. extern long timezone;
  57. #endif
  58. extern char version[];
  59. static char copyright1[] = 
  60. "Copyright 1987 Bdale Garbee, permission granted for non-commercial use.";
  61. static char copyright2[] = 
  62. "Copyright 1988 Dave Trulli NN2Z, permission granted for non-commercial use.";
  63.  
  64. /* comands valid in bm.rc */
  65.  
  66. struct token rccmds[] = {
  67.     "smtp", SMTP,
  68.     "host", HOST,
  69.     "user", USER,
  70.     "edit", EDIT,
  71.     "fullname", NAME,
  72.     "reply", REPLY,
  73.     "maxlet", MAXLET,
  74.     "mbox", MBOX,
  75.     "record", RECORD,
  76.     "screen", SCREEN,
  77.     "folder", FOLDER,
  78.     "mqueue", MQUEUE,
  79.     "zone", TIMEZONE,
  80.     NULLCHAR, 0
  81. };
  82.  
  83. FILE    *mfile = NULLFILE;
  84. char     *hostname = NULLCHAR;        /* name of this host from rc file */
  85. char    *username = NULLCHAR;        /* name of this user from rc file */
  86. char    *fullname = NULLCHAR;        /* fullname of this user from rc file */
  87. char    *replyto = NULLCHAR;        /* address for reply-to header */
  88. char    *maildir = NULLCHAR;        /* defined mail directory */
  89. char    *mqueue = NULLCHAR;        /* defined mqueue outbound directory */
  90. char    *savebox = NULLCHAR;        /* name of the mbox text file */
  91. char    *record = NULLCHAR;        /* record  outbound mail in this file */
  92. char    *folder = NULLCHAR;        /* directory for saveing read mail */
  93. char    *editor = NULLCHAR;        /* user's favorite text editor */
  94. char    notename[9];            /* name of current notesfile */
  95. char    notefile[SLINELEN];        /* full pathname of mail text file */
  96. char    *mfilename = notefile;    /* pointer to current mbox or mail file -f */
  97. int    current;            /* the current message number */
  98. int    nmsgs;            /* the number of messages in the notesfile */
  99. int    newmsgs;        /* Number of new unread message */
  100. int    change;            /* indicates that the mail file has been
  101.                  * changed in this session */
  102. int    fflag = 0;        /* true if current notesfile is not an mbox */
  103. int    qflag = 0;        /* true if bm is used just to queue files */
  104. unsigned maxlet = NLET+1;    /* max number of messages in mailbox */
  105. int    tty = 0;        /* tells if stdin is a tty */
  106. struct let *mbox;        /* pointer to the array of messages */
  107.  
  108.  
  109. #ifndef MAC
  110. char usage[] = "Usage: bm [-u user] [-f file] \n  or bm [-s subject] [-q] addr .. addr\n";
  111. #endif
  112. char badmsg[] = "Invalid Message number %d\n";
  113. char nomail[] = "No messages\n";
  114. char noaccess[] = "Unable to access %s\n";
  115.  
  116. main(argc,argv)
  117. int argc;
  118. char *argv[];
  119. {
  120. #ifndef MAC
  121.     extern int optind;
  122.     extern char *optarg;
  123. #endif
  124.     char *subjectline = NULLCHAR;
  125.     long    tmp;
  126.     int    c;
  127.     int    ret;
  128.  
  129. #if    defined(__TURBOC__) || defined(MICROSOFT)
  130.     (void) fclose(stdaux);
  131.     (void) fclose(stdprn);
  132. #endif
  133.  
  134. #ifdef MAC
  135.     Click_On(1);            /* enable "click to continue" */
  136.     mac_files(1);
  137.     timezone = 0;
  138. #endif
  139.     loadconfig();
  140.  
  141.     if (qflag == 0 && isatty(fileno(stdin))) {
  142.         /* announce ourselves */
  143.         screen_clear();
  144.         printf(" %s\n%s\n%s\n\n",version,copyright1,copyright2);
  145.         tty = 1;
  146.     } 
  147.  
  148.     current = 1;
  149.     nmsgs = 0;
  150.  
  151.     /* check for important directories */
  152.     if(access(maildir,0)){
  153.         printf(noaccess,maildir);
  154.         exit(1);
  155.     }
  156.     if(access(mqueue,0)){
  157.         printf(noaccess,mqueue);
  158.         exit(1);
  159.     }
  160.     strncpy(notename,username,8);
  161.     notename[8] = '\0';
  162. #ifndef MAC
  163.     while ((c = getopt(argc,argv,"u:f:s:q")) != -1) {
  164.         switch(c) {
  165.         case 'f':
  166.             fflag++;
  167.             mfilename = optarg;
  168.             break;
  169.         case 'q':
  170.             qflag++;
  171.             break;
  172.         case 's':
  173.             subjectline = optarg;
  174.             break;
  175.         case 'u':
  176.             strncpy(notename,optarg,8);
  177.             notename[8] = '\0';
  178.             break;
  179.         case '?':
  180.             printf(usage);
  181.             exit(1);
  182.         }
  183.     }
  184.  
  185.     /* set any signal handlers to catch break */
  186.     setsignals();
  187.  
  188.     if(optind < argc){
  189.         dosmtpsend(NULLFILE,&argv[optind],argc-optind,subjectline);
  190.         (void) exit(0);
  191.     }
  192. #endif
  193.     tmp = (long)maxlet * (long)sizeof(struct let);
  194. #ifdef    MSDOS
  195.     /*
  196.     * Since we are in the dos small model make sure that we
  197.     * don't overflow a unsigned short on the number bytes
  198.     * need for mallloc. If not checked malloc will
  199.     * succeed and we will be trashing ourself in no time.
  200.     */
  201.     if ((tmp & 0xffff0000) ||
  202.         (mbox=(struct let *)malloc((unsigned short)tmp)) == (struct let *)NULL){
  203. #else
  204.     if ((mbox=(struct let *)malloc((unsigned)tmp)) == (struct let *)NULL){
  205. #endif
  206.         fprintf(stderr,
  207.         "Can't allocate memory table for %d messages\n",
  208.             maxlet);
  209.         (void) exit(1);
  210.     }
  211. #ifdef MAC
  212.     sprintf(notefile,"%s%s.txt",maildir,notename);
  213. #else
  214.     sprintf(notefile,"%s/%s.txt",maildir,notename);
  215. #endif
  216.     if (!fflag && lockit())
  217.         exit(1);
  218.     ret = initnotes();
  219.     if (!fflag)
  220.         rmlock(maildir,notename);
  221.     if (ret != 0)
  222.         exit(1);
  223.     listnotes();
  224.     
  225.     getcommand();
  226.     return 0;
  227. }
  228.  
  229. loadconfig()
  230. {
  231.     FILE    *rcfp;    /* handle for the configuration file */
  232.     char    rcline[LINELEN]; /* buffer for config file reading */
  233. #ifdef MAC
  234.     char buf[LINELEN];
  235. #endif
  236.     register char *s,*p;
  237.     int line = 0;
  238.     char runcom[LINELEN];
  239.     char *getenv();
  240. #ifdef MAC
  241.         sprintf(runcom,"%s%s",applroot,RUNCOM);
  242. #else
  243. #ifdef UNIX
  244.     /* Try $HOME/RUNCOM */
  245.     if ((p = getenv("HOME")) != NULLCHAR)
  246.         sprintf(runcom, "%s/%s", p, RUNCOM);
  247. #else
  248.     /* check for BMRC in the ENV */
  249.     if ((p = getenv("BMRC")) != NULLCHAR)
  250.         strcpy(runcom,p);
  251. #endif
  252.     else
  253.         strcpy(runcom,RUNCOM);
  254. #endif
  255.     if ((rcfp = fopen(runcom,"r")) == NULLFILE) {    /* open config file */
  256.         printf("Cannot open '%s', check your installation\n",runcom);
  257.         (void) exit(1);
  258.     }
  259.     while (!feof(rcfp)) {
  260.         if (fgets(rcline,LINELEN,rcfp) == NULLCHAR)
  261.             break;
  262.         line++;
  263.         rip(rcline);
  264.         if (*rcline == '\0' || *rcline == ';'|| *rcline == '#')
  265.             continue;
  266.         /* find the argument to the command */
  267.  
  268.         s = rcline;
  269.         /* skip the white space */
  270.         while(*s == ' ' || *s == '\t')
  271.                 s++;
  272.         p = s;
  273.         /* skip the command */
  274.         while(*p && *p != ' ' && *p != '\t')
  275.                 p++;
  276.         /* skip the white space */
  277.         while(*p == ' ' || *p == '\t')
  278.                 p++;
  279.         if (*s == '\0')
  280.             continue;
  281.  
  282.         switch (rc_line_type(s)) {
  283.         case HOST:
  284.             hostname = savestr(p);
  285.             break;
  286.         case USER:
  287.             username = savestr(p);
  288.             break;
  289.         case REPLY:
  290.             replyto = savestr(p);
  291.             break;
  292. #ifndef MAC
  293.         case EDIT:
  294.             editor = savestr(p);
  295.             break;
  296. #endif
  297.         case SMTP:
  298.             maildir = savestr(p);
  299. #ifdef MAC
  300.             sprintf(buf,"%s%s",applroot,maildir);
  301.             free(maildir);
  302.             maildir = savestr(buf);
  303. #endif
  304.             break;
  305.         case NAME:
  306.             fullname = savestr(p);
  307.             break;
  308.         case MAXLET:
  309.             maxlet = atoi(p)+1;
  310.             break;
  311.         case MBOX:
  312.             savebox = savestr(p);
  313.             break;
  314.         case RECORD:
  315.             record = savestr(p);
  316. #ifdef MAC
  317.             sprintf(buf,"%s%s",applroot,record);
  318.             free(record);
  319.             record = savestr(buf);
  320. #endif
  321.             break;
  322. #ifndef MAC
  323.         case SCREEN:
  324. #if    defined(__TURBOC__)
  325.             setvideo(p);
  326. #endif
  327.             break;
  328. #endif
  329.         case FOLDER:
  330.             folder = savestr(p);
  331. #ifdef MAC
  332.             sprintf(buf,"%s%s",applroot,folder);
  333.             free(folder);
  334.             folder = savestr(buf);
  335. #endif
  336.             break;
  337.         case MQUEUE:
  338.             mqueue = savestr(p);
  339. #ifdef MAC
  340.             sprintf(buf,"%s%s",applroot,mqueue);
  341.             free(mqueue);
  342.             mqueue = savestr(buf);
  343. #endif
  344.             break;
  345.         case TIMEZONE:
  346.             tzname[0] = savestr(p);
  347.             break;
  348.         default:
  349.             fprintf(stderr,
  350.             "%s: line %d Invalid command: '%s'\n",
  351.             runcom,line,rcline);
  352.             exit(1);
  353.         }
  354.     }
  355.     (void) fclose(rcfp);
  356.     if(maildir == NULLCHAR)
  357.         maildir = mailspool;
  358.     if(mqueue == NULLCHAR)
  359.         mqueue = mailqdir;
  360.     if(savebox == NULLCHAR)
  361.         savebox = "mbox";
  362. #ifdef MAC
  363.     if(folder != NULLCHAR) {
  364.         sprintf(buf,"%s:%s",folder,savebox);
  365.         free(folder);
  366.         free(savebox);
  367.         savebox = savestr(buf);
  368.     }
  369. #endif
  370.     if(hostname == NULLCHAR) {
  371.         fprintf(stderr,"%s: hostname not set\n",runcom);
  372.         exit(1);
  373.     }
  374.     if(username == NULLCHAR) {
  375.         fprintf(stderr,"%s: username not set\n",runcom);
  376.         exit(1);
  377.     }
  378. }
  379.  
  380. /* return the line_type from a line of the configuration file */
  381. rc_line_type(s)
  382. register char *s;
  383. {
  384.     register struct token *tp;
  385.     for (tp = rccmds; tp->str != NULLCHAR; tp++) {
  386.         if (strncmp(tp->str,s,strlen(tp->str)) == 0)
  387.             return tp->type;
  388.     }
  389.     return (NONE);
  390. }
  391.  
  392. /* replace terminating end of line marker(s) with null */
  393. rip(s)
  394. register char *s;
  395. {
  396.     for (; *s; s++)
  397.         if (*s == '\r' || *s == '\n') {
  398.             *s = '\0';
  399.             break;
  400.         }
  401. }
  402.  
  403. /* copy a string return a pointer to it */
  404. char *
  405. savestr(s)
  406. char *s;
  407. {
  408.     register  char *p;
  409.     p = malloc(strlen(s)+1);
  410.     if (p == NULLCHAR) 
  411.         printf("No more memory\n");
  412.     else
  413.         strcpy(p,s);
  414.     return p;
  415. }
  416.  
  417. dohelp()
  418. {
  419.     screen_clear();
  420.     printf("\n\n");
  421.     printf(" d [msglist]           delete a message\n");
  422.     printf(" m userlist            mail a message\n");
  423.     printf(" s [msglist] [file]    save message in file (default mbox)\n");
  424.     printf(" w [msglist] file      save message in file no header\n");
  425.     printf(" f [msg]               forward message\n");
  426.     printf(" b [msg]               bounce message (remail)\n");
  427.     printf(" r [msg]               reply to a message\n");
  428.     printf(" u [msglst]            undelete a message\n");
  429. #ifdef MAC
  430.     printf(" p [msglst]            print message on printer\n");
  431. #else
  432.     printf(" p [msglst]            print message on printer (DOS only)\n");
  433. #endif
  434.     printf(" .                     display current message\n");
  435.     printf(" h                     display message headers in notefile\n");
  436.     printf(" l                     list unsent messages\n");
  437.     printf(" k                     kill unsent messages\n");
  438.     printf(" n [file]              display or change notesfile\n");
  439.     printf(" #                     where # is the number of message to read\n");
  440.     printf(" x                     quit without changing mail file\n");
  441.     printf(" q                     quit\n");
  442. #ifndef MAC
  443.     printf(" ! cmd                 run dos command\n");
  444. #endif
  445.     printf(" $                     sync the notefile\n");
  446.     printf(" ?                     print this help screen\n");
  447. }
  448.  
  449.  
  450. /* save a message list in a file in mailbox format */
  451. savemsg(argc,argv)
  452. int argc;
  453. register char *argv[];
  454. {
  455.     register char *savefile;
  456.     int msgnum;
  457.     int    i;
  458.     FILE *tfile;
  459.     char buf[LINELEN];
  460.  
  461.     if (mfile == NULLFILE){
  462.         printf(nomail);
  463.         return;
  464.     }
  465.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  466.         savefile = savebox;
  467.     } else {
  468.         savefile = argv[argc - 1];
  469.         --argc;
  470.         /* if it is just a file name and not a path name then check
  471.         ** for a folder path defined and use that path to
  472.         ** save the file.
  473.         */
  474. #ifdef MAC
  475.         if (strpbrk(savefile,":") == NULLCHAR && folder != NULLCHAR) {
  476.             sprintf(buf,"%s%s:%s",applroot,folder,savefile);
  477. #else
  478.         if (strpbrk(savefile,"/\\") == NULLCHAR && folder != NULLCHAR) {
  479.             sprintf(buf,"%s/%s",folder,savefile);
  480. #endif
  481.             savefile = buf;
  482.         }
  483.     }
  484.     if ((tfile = fopen(savefile,"a")) == NULLFILE) {
  485.         perror(savefile);
  486.         return;
  487.     }
  488.     if (argc == 0)
  489.         msgtofile(current, tfile, 0);
  490.     else {
  491.         for (i = 0; i < argc; i++) {
  492.             msgnum = atoi(argv[i]);
  493.             if (msgnum >= 1 && msgnum <= nmsgs)
  494.                 msgtofile(msgnum, tfile, 0);
  495.             else
  496.                 printf(badmsg,msgnum);
  497.         }
  498.     }
  499.         (void) fclose(tfile);
  500.         printf("%s appended\n",savefile);
  501. }
  502.  
  503. #if defined(MSDOS) || defined(MAC)
  504. /* send messages to the print device */
  505. printmsg(argc,argv)
  506. int argc;
  507. char *argv[];
  508. {
  509.     FILE *prn;
  510.     int msgnum;
  511.     int    i;
  512.  
  513.     if (mfile == NULLFILE){
  514.         printf(nomail);
  515.         return;
  516.     }
  517. #ifndef MAC
  518.     if ((prn = fopen("PRN","a")) == NULL) {
  519.         perror("PRN");
  520.         return;
  521.     }
  522. #endif
  523. #ifdef MAC
  524.     Echo_to_Printer(1);
  525. #endif
  526.     if (argc == 0)
  527. #ifdef MAC
  528.         msgtofile(current, stdout, 0);
  529. #else
  530.         msgtofile(current, prn, 0);
  531. #endif
  532.     else {
  533.         for (i = 0; i < argc; i++) {
  534.             msgnum = atoi(argv[i]);
  535.             if (msgnum >= 1 && msgnum <= nmsgs)
  536. #ifdef MAC
  537.                 msgtofile(msgnum, stdout, 0);
  538. #else
  539.                 msgtofile(msgnum, prn, 0);
  540. #endif
  541.             else
  542.                 printf(badmsg,msgnum);
  543.         }
  544.     }
  545. #ifdef MAC
  546.     Echo_to_Printer(0);
  547. #else
  548.     fclose(prn);
  549. #endif
  550. }
  551. #endif
  552.  
  553. writemsg(argc,argv)
  554. int argc;
  555. char *argv[];
  556. {
  557.     char *writefile;
  558.     int msgnum;
  559.     int    i;
  560.     FILE *tfile;
  561.  
  562.     if (mfile == NULLFILE){
  563.         printf(nomail);
  564.         return;
  565.     }
  566.     if (argc == 0 || isdigit(*argv[argc - 1])) {
  567.         printf("no file specified\n");
  568.         return;
  569.     } else {
  570.         writefile = argv[argc - 1];
  571.         --argc;
  572.     }
  573.     if ((tfile = fopen(writefile,"a")) == NULLFILE) {
  574.         perror(writefile);
  575.         return;
  576.     }
  577.     if (argc == 0)
  578.         msgtofile(current, tfile, 1);
  579.     else {
  580.         for (i = 0; i < argc; i++) {
  581.             msgnum = atoi(argv[i]);
  582.             if (msgnum >= 1 && msgnum <= nmsgs)
  583.                 msgtofile(msgnum, tfile, 1);
  584.             else
  585.                 printf(badmsg,msgnum);
  586.         }
  587.     }
  588.     (void) fclose(tfile);
  589.     printf("%s appended\n",writefile);
  590. }
  591.  
  592. bmexit(x)
  593. int x;
  594. {
  595.     if(!fflag && lockit())
  596.         exit(1);
  597.     (void) closenotes();
  598.     if (!fflag)
  599.         rmlock(maildir,notename);
  600.     mac_cleanup();
  601.     exit(x);
  602. }
  603.  
  604. /* this is the main command processing loop */
  605. getcommand()
  606. {
  607.     FILE *tfile, *tmpfile();
  608.     char    command[LINELEN];    /* command line */
  609.     char    *args[MAXARGS];
  610.     int    nargs;
  611.     char    *cp;
  612.     register int    msgnum;
  613.     register int    i;
  614.     int ret;
  615.  
  616.     printf("\nType ? for help.\n");
  617.  
  618.     /* command parsing loop */
  619.     while(1) {
  620.         printf("\"%s\"> ",notename);
  621.         gets(command);
  622.  
  623.         if (feof(stdin))        /* someone hit ^Z! */
  624.             strcpy(command,"q");    /* treat it like 'q' */
  625. #ifndef MAC            
  626.         if(*command == '!') {
  627.             if (system(&command[1]))
  628.                 perror("system");
  629.             continue;
  630.         }
  631. #endif
  632.         if (*command) {
  633.             cp = command;
  634.             while (*cp && *cp != ' ')
  635.                 cp++;
  636.             nargs = parse(cp,args,MAXARGS);
  637.         }
  638.  
  639.         switch (*command) {
  640.         case 'm':        /* send msg */
  641.             if (nargs == 0) {
  642.                 printf("To: ");
  643.                 gets(command);
  644.                 nargs = parse(command,args,MAXARGS);
  645.             }
  646.             dosmtpsend(NULLFILE,args,nargs,NULLCHAR);
  647.             break;
  648.  
  649.         case 's':        /* save current msg to file */
  650.             savemsg(nargs,args);
  651.             break;
  652.  
  653.         case 'w':        /* write current msg to file */
  654.             writemsg(nargs,args);
  655.             break;
  656.  
  657.         case 'x':        /* abort */
  658.             (void) fclose(mfile);
  659.             (void) exit(0);
  660.             /* NOTREACHED */
  661.             break;
  662.  
  663.         case 'p':        /* print message */
  664. #ifdef MAC
  665.             printmsg(nargs,args);
  666. #else
  667. #ifdef MSDOS
  668.             printmsg(nargs,args);
  669. #else
  670.             printf("Command not available in this version\n");
  671. #endif
  672. #endif
  673.             break;
  674.  
  675.         case 'r':            /* reply */
  676.             if (nargs == 0)
  677.                 msgnum = current;
  678.             else
  679.                 msgnum = atoi(args[0]);
  680.             if (msgnum >= 1 && msgnum <= nmsgs)
  681.                 reply(msgnum);
  682.             else
  683.                 printf(badmsg,msgnum);
  684.             break;
  685.  
  686.         case 'f':
  687.             if(nargs == 0)
  688.                 msgnum = current;
  689.             else 
  690.                 msgnum = atoi(args[0]);
  691.             if (msgnum < 1 || msgnum > nmsgs) {
  692.                 printf(badmsg,msgnum);
  693.                 break;
  694.             }
  695.             if((tfile = tmpfile()) == NULLFILE)
  696.                 printf("\nCannot open temp file\n");
  697.             else {
  698.                 msgtofile(msgnum,tfile,0);
  699.                 fseek(tfile,0L,0);
  700.                 printf("To: ");
  701.                 gets(command);
  702.                 nargs = parse(command,args,MAXARGS);
  703.                 dosmtpsend(tfile,args,nargs,NULLCHAR);
  704.                 (void) fclose(tfile);
  705.             }
  706.             break;
  707.  
  708.         case 'b':        /* bounce a message */
  709.             if(nargs == 0)
  710.                 msgnum = current;
  711.             else 
  712.                 msgnum = atoi(args[0]);
  713.             if (msgnum < 1 || msgnum > nmsgs) {
  714.                 printf(badmsg,msgnum);
  715.                 break;
  716.             }
  717.             if((tfile = tmpfile()) == NULLFILE)
  718.                 printf("\nCannot open temp file\n");
  719.             else {
  720.                 msgtofile(msgnum,tfile,0);
  721.                 fseek(tfile,0L,0);
  722.                 printf("To: ");
  723.                 gets(command);
  724.                 nargs = parse(command,args,MAXARGS);
  725.                 bouncemsg(tfile,args,nargs);
  726.                 (void) fclose(tfile);
  727.             }
  728.             break;
  729.  
  730.         case 'u':
  731.             if (nargs == 0)
  732.                 mbox[current].status &= ~DELETE;
  733.             else
  734.                 for (i = 0; i < nargs; i++) {
  735.                     msgnum = atoi(args[i]);
  736.                     if( msgnum >= 1 && msgnum <= nmsgs)
  737.                         mbox[msgnum].status &= ~DELETE;
  738.                     else
  739.                         printf(badmsg,msgnum);
  740.                 }
  741.             break;
  742.  
  743.         case 'l':        /* display unsent messages */
  744.             listqueue();
  745.             break;
  746.         case 'k':
  747.             if (nargs == 0)
  748.                 printf("No job id specified\n");
  749.             else
  750.                 for (i = 0; i < nargs; i++) 
  751.                     killjob(args[i]);
  752.             break;
  753.  
  754.         case 'n':     /* display or change notefiles */
  755.             mboxnames(nargs,args);
  756.             break;
  757.         case 'q':        /* quit */
  758.             if (isnewmail()) {
  759.                 printf("New mail has arrived\n");
  760.                 reinit();
  761.             } else
  762. #ifdef MAC
  763.                 Click_On(0);    /* disable "CoC" for normal exit */
  764. #endif
  765.                 bmexit(0);
  766.             /* NOTREACHED */
  767.             break;
  768.         case '$':
  769.             reinit();
  770.             break;
  771.  
  772.         case 'd':        /* delete a message */
  773.             if (nargs == 0)
  774.                 delmsg(current);
  775.             else
  776.                 for ( i = 0; i < nargs; i++) {
  777.                     msgnum = atoi(args[i]);
  778.                     if( msgnum >= 1 && msgnum <= nmsgs)
  779.                         delmsg(msgnum);
  780.                     else
  781.                         printf(badmsg,msgnum);
  782.                 }
  783.             break;
  784.  
  785.         case 'h':        /* list message headers in notesfile */
  786.  
  787.             listnotes();
  788.             break;
  789.  
  790.         case '\0':    /* a blank line prints next message */
  791.             printnext();
  792.             break;
  793.  
  794.         case '?':        /* help */
  795. #ifdef MAC
  796.             DoHelp("\p","\pBM Internet Mailer","\pApple Macintosh Version",
  797.                     "\p⌐Copyright 1988,B. Garbee",TRUE,0L);
  798.             DisposeHelp();
  799. #else
  800.             dohelp();
  801. #endif
  802.             break;
  803.  
  804.         case  '.':
  805.             displaymsg(current);
  806.             break;
  807.         default:
  808.             if (!isdigit(*command))
  809.                 printf("Invalid command - ? for help\n");
  810.             else {
  811.                 msgnum = atoi(command);
  812.                 if (msgnum < 0 || msgnum > nmsgs)
  813.                     printf(badmsg,msgnum);
  814.                 else {
  815.                     current = msgnum;
  816.                     displaymsg(current);
  817.                 }
  818.             }
  819.             break;
  820.         }
  821.     }
  822. }
  823.  
  824. /* list or change mbox */
  825. mboxnames(argc,argv)
  826. int argc;
  827. char *argv[];
  828. {
  829.     register char *cp;
  830.     int ret;
  831.     char    line[80];
  832.     char    buf[LINELEN];
  833.  
  834.     if(argc != 0) {
  835.         if(!fflag && lockit())
  836.             return;
  837.         ret = closenotes();
  838.         if (!fflag)
  839.             rmlock(maildir,notename);
  840.             if (ret != 0)
  841.                 exit(1);
  842.             if (strpbrk(argv[0],"/\\") != NULLCHAR) {
  843.                 fflag = 1;
  844.                 mfilename = argv[0];
  845.             } else {
  846.                 fflag = 0;
  847.                 mfilename = notefile;
  848.                 strncpy(notename,argv[0],8);
  849.                 notename[8] = '\0';
  850. #ifdef MAC
  851.                 sprintf(notefile,"%s%s.txt",maildir,notename);
  852. #else
  853.                 sprintf(notefile,"%s/%s.txt",maildir,notename);
  854. #endif
  855.             }
  856.             if (!fflag && lockit()) {
  857.                 mfile = NULLFILE;
  858.                 printf("Mail file is busy\n");
  859.                 return;
  860.             }
  861.             ret = initnotes();
  862.             if (!fflag)
  863.                 rmlock(maildir,notename);
  864.             if (ret != 0)
  865.                 exit(1);
  866.             listnotes();
  867.  
  868.         } else {  /* he wants to see what notefiles there are */
  869. #ifdef MAC
  870.             sprintf(buf,"%s*.txt",maildir);
  871. #else
  872.             sprintf(buf,"%s/*.txt",maildir,notename);
  873. #endif
  874.             filedir(buf,0,line);
  875.             while(line[0] != '\0') {
  876.                 cp = strchr(line,'.');
  877.                 *cp = '\0';
  878.                 printf("notesfile -> %s\n",line);
  879.                 filedir(buf,1,line);
  880.             }
  881.         }
  882. }
  883.  
  884. reinit()
  885. {
  886.     int ret;
  887.     if (!fflag && lockit())
  888.         return;
  889.     ret = closenotes();
  890.     if (!fflag)
  891.         rmlock(maildir,notename);
  892.     if (ret != 0)
  893.         exit(1);
  894.     if (!fflag && lockit()) {
  895.         mfile = NULLFILE;
  896.         printf("Mail file is busy\n");
  897.         return;
  898.     }
  899.     ret = initnotes();
  900.     if (!fflag)
  901.         rmlock(maildir,notename);
  902.     if (ret != 0)
  903.         exit(1);
  904.     listnotes();
  905. }
  906.  
  907.